語言文字事件有趣的事情,英文由26個字母反覆組合,描述各種現象。中文永字八筆,構築千萬象形文字。在電腦的世界裡,一切的一切都是由無數個0和1所表示,你所從螢幕見到的任何文字、圖片、影片都是。在文字的表示法中,有一個最早誕生的編碼方式--ASCII Code。從某種角度來說,它也是在電腦世界中最安全的表示方式。
我們介紹過如何安全的儲存JavaScript程式碼而不受到編碼影響。如何在有限的字元中,在網頁HTML表達多國語言的文字。分享過DNS與電腦是如何認識IDN。這次,要來說說URL裡關於Path字段的編碼方式。
當我們瀏覽https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third
[^1],實際上可以將這個URL拆分成好幾個部分來看。
+-------------------+---------------------+
| Part | Data |
+-------------------+---------------------+
| Scheme | https |
| User | bob |
| Password | bobby |
| Host | www.lunatech.com |
| Port | 8080 |
| Path | /file;p=1 |
| Path parameter | p=1 |
| Query | q=2 |
| Fragment | third |
+-------------------+---------------------+
https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third
\___/ \_/ \___/ \______________/ \__/\_______/ \_/ \___/
| | | | | | \_/ | |
Scheme User Password Host Port Path | | Fragment
\_____________________________/ | Query
| Path parameter
Authority
以網頁瀏覽來說,協議或Scheme通常是HTTP或HTTPS。然後通常缺省的帳號與密碼,因爲以身份驗證來說,現今更常使用其他種方式驗證,比如OpenID。緊接着可能是使用puncode編碼表示的Host和Port。最後是今天要提到的部分 -- Path。
在仔細看Path後的部分,通常是網頁應用框架、SPA(Single Page Application)或是瀏覽器本身會關注的資訊,包含了主要Path、Query和Fragment。其中Query由?
開始,通常用x-www-form-urlencoded
方式編碼;Fragment由#
開始,又被稱爲錨點(Anchor)
Domain或稱之爲Host的部分使用puncode編碼,而後續的Path則是使用百分號編碼(Percent-encoding)[^2]。
百分號編碼主要定義了一些保留字,使用保留字的字元,必須先轉換成有百分號(%
)開頭,加上數字的表示方式。
常見的保留字包含#
、&
、/
、:
、;
、=
、?
。?
後的表示Query的部分;#
後的是Fragment。因此若需要使用到,需要先經過轉義。像是/
就需要轉義成%2F
;空白通常轉換成%20
;+
轉換成%2B
。
通常來說可以使用ASCII表的字,轉換成百分號編碼就是百分號(%
)加上以16進位表示的ASCII,或是使用16進位的UTF-8表示的數字。使用編碼過後的結果與使用未保留的字元,有些情況下表示意義相同。比如可以在www-data
目錄下再建立一個目錄sub
,然後建立index.html
。
<!-- www-data/sub/index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>percent-encoding</title>
</head>
<body>
<h1>Hello, World</h1>
</body>
</html>
然後透過docker啓動nginx:
docker run --name nginx --rm -p 8080:80 -v "${PWD}/www-data":/usr/share/nginx/html nginx
現在除了 http://localhost:8080/sub/index.html
可以瀏覽到該頁面外,還可以透過
http://localhost:8080/sub%2findex.html
瀏覽,更甚甚至可以透過 http://localhost:8080/sub%2f%69%6e%64%65%78%2e%68%74%6d%6c
瀏覽。
這次我們在www-data
目錄下建立一個?.html
檔案
<!-- www-data/?.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>percent-encoding</title>
</head>
<body>
<h1>給我一個大大的?</h1>
</body>
</html>
然後瀏覽 http://xn--ji8h.127.0.0.1.nip.io:8080/%F0%9F%8D%8C.html
或 http://xn--ji8h.127.0.0.1.nip.io:8080/%F0%9F%8D%8C.html 看看。
是的我偷渡IDN的概念進來。只可惜我的瀏覽器沒辦法在host部分顯式emoji。
[^1]: Stackoverflow-URL encoding the space character: + or %20?。取用時間:2022-09-21。
[^2]: 維基百科-百分號編碼。取用時間:2022-09-21。
可惜在iT邦幫忙有些emoji顯式好像不算正常,會顯式
?
。
不過沒關係你可以到我的網站閱讀看看。
本文同時發表於我的隨筆